import tkinter as tk
from tkinter import ttk
import time
import random
import statistics
import sqlite3
from datetime import datetime
from zsm import *
from tkinter import Toplevel,PhotoImage,CENTER,Label,BOTH,ttk
class EsportsReactionTest:
    def __init__(self, master):
        self.master = master
        master.title("+++游戏玩家反应测试工具+++    by:风二西  2025.03.01")
        master.geometry("800x600")
        master.configure(bg='#F5F5F5')

        # 职业级段位配置（单位：秒）
        self.rank_config = [
            (0.15, "王者", '#FFD700'),  # 职业选手标准 0.15秒
            (0.18, "星耀", '#9C27B0'),  # 半职业选手
            (0.21, "钻石", '#2196F3'),  # 高级玩家
            (0.24, "铂金", '#3F51B5'),  # 中级玩家
            (0.27, "黄金", '#FF9800'),  # 普通玩家
            (0.30, "白银", '#607D8B'),  # 新手玩家
            (float('inf'), "青铜", '#795548')
        ]

        # 测试配置
        self.delay_range = (1, 2)  # 准备时间3-5秒
        self.cooldown = 1  # 测试间隔冷却时间
        self.max_tests = 5
        self.current_round = []
        self.test_running = False
        self.green_active = False

        # 初始化数据库
        self.conn = sqlite3.connect('pro_reaction_data.db')
        self.create_table()

        # 创建样式
        self.create_styles()

        # 创建界面
        self.create_notebook()
        self.reset_test()

    def create_styles(self):
        """创建自定义样式"""
        style = ttk.Style()
        style.configure('TButton', font=('微软雅黑', 10), padding=6)
        style.configure('Accent.TButton',
                        background='#4CAF50',
                        foreground='white',
                        font=('微软雅黑', 10, 'bold'))
        style.map('Accent.TButton',
                  background=[('active', '#45a049'), ('disabled', '#BDBDBD')])
        style.configure('Treeview.Heading', font=('微软雅黑', 11, 'bold'))
        style.configure('Treeview', font=('微软雅黑', 10), rowheight=28)

    def create_table(self):
        """创建数据库表"""
        cursor = self.conn.cursor()
        cursor.execute('''CREATE TABLE IF NOT EXISTS pro_records
                     (id INTEGER PRIMARY KEY AUTOINCREMENT,
                      test_time TEXT,
                      avg_time REAL,
                      best_time REAL,
                      valid_tests INTEGER,
                      rank TEXT)''')
        self.conn.commit()

    def create_notebook(self):
        """创建分页导航"""
        self.notebook = ttk.Notebook(self.master)

        # 创建三个页面
        self.home_frame = self.create_page("主页")
        self.record_frame = self.create_page("测试记录")
        self.rank_frame = self.create_page("段位标准")

        self.notebook.add(self.home_frame, text=" 主页")
        self.notebook.add(self.record_frame, text=" 记录")
        self.notebook.add(self.rank_frame, text=" 标准")
        self.notebook.pack(fill=tk.BOTH, expand=True)

        # 初始化各页面
        self.create_home_ui()
        self.create_record_ui()
        self.create_rank_ui()

    def create_page(self, text):
        """创建基础页面框架"""
        frame = ttk.Frame(self.notebook, padding=10)
        return frame

    def create_home_ui(self):
        """主页布局"""
        # 顶部控制栏
        control_frame = ttk.Frame(self.home_frame)
        control_frame.pack(fill=tk.X, pady=8)

        self.start_btn = ttk.Button(
            control_frame,
            text="开始测试",
            command=self.toggle_test,
        )
        self.start_btn.pack(side=tk.LEFT, padx=5)

        ttk.Button(
            control_frame,
            text="赞赏作者",
            command=lambda: self.show_support(),
        ).pack(side=tk.LEFT, padx=5)

        # 点击测试区域
        self.react_canvas = tk.Canvas(
            self.home_frame,
            bg='#FFFFFF',
            height=250,
            highlightthickness=1,
            highlightbackground='#E0E0E0'
        )
        self.react_canvas.pack(fill=tk.BOTH, expand=True, pady=12)
        self.react_canvas.bind("<Button-1>", self.record_reaction)

        # 状态提示
        self.status_label = ttk.Label(
            self.home_frame,
            text="准备就绪，点击开始按钮进行测试",
            font=('微软雅黑', 11),
            foreground='#616161'
        )
        self.status_label.pack(pady=10)

    def show_support(self):
        """显示支持信息"""
        self.zsm_windows = Toplevel(self.root)
        # 替换窗口浮于上方
        self.zsm_windows.wm_attributes("-topmost", 1)
        self.zsm_windows.title('赞赏作者')
        self.photo1 = PhotoImage(data=zsm123)
        self.zsm1 = Label(self.zsm_windows, image=self.photo1,
                          compound=CENTER)
        self.zsm1.pack(fill=BOTH, expand=True)


    def create_record_ui(self):
        """记录页布局"""
        columns = ("测试时间", "平均反应", "最佳反应", "有效次数", "段位")
        self.record_tree = ttk.Treeview(
            self.record_frame,
            columns=columns,
            show='headings',
            selectmode='browse'
        )

        # 配置列
        col_widths = [200, 100, 100, 80, 150]
        for col, width in zip(columns, col_widths):
            self.record_tree.column(col, width=width, anchor='center')
            self.record_tree.heading(col, text=col)

        # 滚动条
        scrollbar = ttk.Scrollbar(self.record_frame, orient="vertical", command=self.record_tree.yview)
        self.record_tree.configure(yscrollcommand=scrollbar.set)

        self.record_tree.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
        scrollbar.pack(side=tk.RIGHT, fill=tk.Y)

        # 加载历史数据
        self.load_history()

    def create_rank_ui(self):
        """段位标准页布局"""
        columns = ("段位名称", "时间要求", "职业参考")
        self.rank_tree = ttk.Treeview(
            self.rank_frame,
            columns=columns,
            show='headings'
        )

        # 配置列
        col_config = [
            ("段位名称", 150),
            ("时间要求", 200),
            ("职业参考", 250)
        ]
        for col, width in col_config:
            self.rank_tree.column(col, width=width, anchor='center')
            self.rank_tree.heading(col, text=col)

        # 填充数据
        references = [
            "职业选手",
            "半职选手",
            "高端玩家",
            "资深玩家",
            "普通玩家",
            "新手玩家",
            "需要练习"
        ]
        for i in range(len(self.rank_config)):
            min_time = self.rank_config[i][0] * 1000

            # 修改时间范围显示逻辑
            if i == 0:  # 处理第一个段位
                time_range = f"0-{min_time:.0f}ms"
            elif i == len(self.rank_config) - 1:  # 处理最后一个段位
                time_range = f"300ms-999ms"
            else:  # 处理中间段位（修复了原代码的max_time错误）
                max_time = self.rank_config[i - 1][0] * 1000  # 获取下一段位的阈值
                time_range = f"{max_time:.0f}ms-{min_time:.0f}ms"

            self.rank_tree.insert('', 'end', values=(
                self.rank_config[i][1],  # 段位名称
                time_range,  # 时间范围
                references[i]  # 职业参考
            ), tags=(self.rank_config[i][2],))

        self.rank_tree.pack(fill=tk.BOTH, expand=True)

    def load_history(self):
        """加载历史记录"""
        cursor = self.conn.cursor()
        cursor.execute("SELECT test_time, avg_time, best_time, valid_tests, rank FROM pro_records ORDER BY id DESC")
        for row in cursor.fetchall():
            self.record_tree.insert('', 'end', values=(
                row[0],
                f"{row[1] * 1000:.1f}ms",
                f"{row[2] * 1000:.1f}ms",
                row[3],
                row[4]
            ))

    def reset_test(self):
        """重置测试状态"""
        self.test_running = False
        self.current_round = []
        self.react_canvas.config(bg='#FFFFFF')
        self.green_active = False
        if hasattr(self, 'timeout_id'):
            self.master.after_cancel(self.timeout_id)

    def toggle_test(self):
        """切换测试状态"""
        if not self.test_running:
            self.test_running = True
            self.start_btn.config(text="停止测试")
            self.status_label.config(text="测试进行中...", foreground='#616161')
            self.run_single_test()
        else:
            self.reset_test()
            self.start_btn.config(text="开始测试")
            self.status_label.config(text="测试已停止")

    def run_single_test(self):
        """执行单次测试（增加冷却机制）"""
        if self.test_running and len(self.current_round) < self.max_tests:
            self.green_active = False
            self.react_canvas.config(bg='#FFFFFF')
            self.status_label.config(text="准备中，请等待...", foreground='#616161')
            delay = random.uniform(*self.delay_range)
            # 添加冷却时间机制
            self.master.after(int(self.cooldown * 1000),
                              lambda: self.master.after(int(delay * 1000), self.show_target))

    def show_target(self):
        """显示点击目标并启动超时检测"""
        if self.test_running:
            self.green_active = True
            self.start_time = time.perf_counter()
            self.react_canvas.config(bg='#4CAF50')
            self.timeout_id = self.master.after(800, self.handle_timeout)  # 800ms超时

    def handle_timeout(self):
        """处理超时未点击"""
        if self.green_active:
            self.current_round.append(None)
            self.status_label.config(
                text=f"超时未点击！已记录次数：{len(self.current_round)}/{self.max_tests}",
                foreground='red'
            )
            self.check_round_complete()

    def record_reaction(self, event):
        """记录反应时间（严格模式）"""
        if not self.test_running:
            return

        # 处理点击事件
        reaction_time = time.perf_counter() - self.start_time if self.green_active else None

        if hasattr(self, 'timeout_id'):
            self.master.after_cancel(self.timeout_id)

        # 记录结果
        if self.green_active:
            if reaction_time < 0.1:
                self.status_label.config(text="无效点击（抢跑）！", foreground='red')
                self.current_round.append(None)
            else:
                self.current_round.append(reaction_time)
                self.status_label.config(
                    text=f"有效反应：{reaction_time * 1000:.1f}ms ({len(self.current_round)}/{self.max_tests})",
                    foreground='green'
                )
        else:
            self.current_round.append(None)
            self.status_label.config(
                text=f"无效点击（时机错误）！({len(self.current_round)}/{self.max_tests})",
                foreground='orange'
            )

        self.green_active = False
        self.master.after(int(self.cooldown * 1000), self.check_round_complete)

    def check_round_complete(self):
        """检查是否完成一轮测试"""
        if len(self.current_round) >= self.max_tests:
            self.save_round_data()
            self.toggle_test()
        else:
            self.run_single_test()

    def save_round_data(self):
        """保存数据到数据库"""
        valid_times = [t for t in self.current_round if t is not None]

        avg_time = statistics.mean(valid_times) if valid_times else 0
        best_time = min(valid_times) if valid_times else 0
        valid_count = len(valid_times)

        rank = self.get_rank(avg_time) if valid_count > 0 else "无效测试"

        # 写入数据库
        cursor = self.conn.cursor()
        cursor.execute('''INSERT INTO pro_records 
                       (test_time, avg_time, best_time, valid_tests, rank)
                       VALUES (?, ?, ?, ?, ?)''',
                       (datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
                        avg_time,
                        best_time,
                        valid_count,
                        rank))
        self.conn.commit()

        # 更新界面
        self.record_tree.insert('', 0, values=(
            datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
            f"{avg_time * 1000:.1f}ms" if valid_count > 0 else "--",
            f"{best_time * 1000:.1f}ms" if valid_count > 0 else "--",
            valid_count,
            rank
        ))

    def get_rank(self, reaction_time):
        """获取段位（仅限有效测试）"""
        # 遍历段位配置（假设已按阈值升序排列）
        for i in range(len(self.rank_config)):
            # 王者段位特殊处理（最高段位）
            if i == 0 and reaction_time <= self.rank_config[i][0]:
                return f"{self.rank_config[i][1]} ★★★★★"

            # 中间段位判断
            if i < len(self.rank_config) - 1:
                lower = self.rank_config[i-1][0]
                upper = self.rank_config[i][0]

                if lower < reaction_time <= upper:
                    # 计算星级（越接近下限星级越高）
                    time_range = upper - lower
                    progress = (upper - reaction_time) / time_range
                    stars = min(5, max(1, int(progress * 5)))  # 确保1-5颗星
                    return f"{self.rank_config[i][1]} {'★' * stars}"

        # 青铜段位（无星级）
        return "青铜"

    def __del__(self):
        """关闭数据库连接"""
        self.conn.close()


if __name__ == "__main__":
    root = tk.Tk()
    app = EsportsReactionTest(root)
    root.mainloop()